package com.qs.gateway.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


/**
 * 解析请求的来源 IP 作为限流 KEY
 */
@Configuration
public class GatewayConfig {

    private Logger logger = LoggerFactory.getLogger(GatewayConfig.class);

    @Bean
    public KeyResolver ipKeyResolver() {
        return new KeyResolver() {
            @Override
            public Mono<String> resolve(ServerWebExchange exchange) {
                // 获取请求的 IP
                return Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
            }
        };
    }

    /**
     * 测试多个 GlobalFilter 执行顺序
     * 结论：GlobalFilter 执行分为 pre 和 post，Order注解值越小，pre 执行优先级越高，post 执行优先级越低
     *
     * @since 2022-04-20 10:25:35
     */
    @Bean
    @Order(1)
    public GlobalFilter firstGlobalFilter() {
        return (exchange, chain) -> {
            logger.info("[first][pre]");
            return chain.filter(exchange).then(Mono.fromRunnable(() -> logger.info("[first][post]")));
        };
    }

    @Bean
    @Order(2)
    public GlobalFilter sendGlobalFilter() {
        return (exchange, chain) -> {
            logger.info("[second][pre]");
            return chain.filter(exchange).then(Mono.fromRunnable(() -> logger.info("[second][post]")));
        };
    }

    @Bean
    @Order(3)
    public GlobalFilter thirdGlobalFilter() {
        return (exchange, chain) -> {
            logger.info("[third][pre]");
            return chain.filter(exchange).then(Mono.fromRunnable(() -> logger.info("[third][post]")));
        };
    }
}
